using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Windy.TurtleDrawing;
using Windy.Transformations;
using System.Diagnostics.Contracts;
using System.Windows.Media;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Windows;

namespace Windy.DragonCurve
{
    public class DragonCurveScheme
    {
        public string Name { get; set; }
        public List<Symbols> InitialSymbols { get; set; }
        public List<ITransformRule<Symbols>> CurveRules { get; set; }
        public List<ITransformRule<Symbols>> PlotRules { get; set; }
        public double? StepAngel { get; set; }

        public DragonCurveScheme SetupName(string name)
        {
            this.Name = name;
            return this;
        }
        public DragonCurveScheme SetupInitialSymbols(params Symbols[] initSymbols)
        {
            return SetupInitialSymbols(initSymbols as IEnumerable<Symbols>);
        }
        public DragonCurveScheme SetupInitialSymbols(IEnumerable<Symbols> initSymbols)
        {
            this.InitialSymbols = initSymbols.ToList();
            return this;
        }
        public DragonCurveScheme SetupCurveRules(params ITransformRule<Symbols>[] curveRules)
        {
            return SetupCurveRules(curveRules as IEnumerable<ITransformRule<Symbols>>);
        }
        public DragonCurveScheme SetupCurveRules(IEnumerable<ITransformRule<Symbols>> curveRules)
        {
            if (curveRules == null)
                CurveRules = null;
            else
                CurveRules = curveRules.ToList();

            return this;
        }
        public DragonCurveScheme SetupPlotRules(params ITransformRule<Symbols>[] plotRules)
        {
            return SetupPlotRules(plotRules as IEnumerable<ITransformRule<Symbols>>);

        }
        public DragonCurveScheme SetupPlotRules(IEnumerable<ITransformRule<Symbols>> plotRules)
        {
            if (plotRules == null)
                PlotRules = null;
            else
                PlotRules = plotRules.ToList();

            return this;
        }
        public DragonCurveScheme SetupStepAngel(double? angel)
        {
            if (angel == null)
                return SetupStepAngelDegree(null);
            else
                return SetupStepAngelDegree(angel.Value.ToDegree());
        }
        public DragonCurveScheme SetupStepAngelDegree(double? angel)
        {
            StepAngel = angel;
            return this;  
        }

        public bool IsValid
        {
            get
            {
                return
                    StepAngel != null &&
                    InitialSymbols != null &&
                    InitialSymbols.Any() &&
                    CurveRules != null &&
                    CurveRules.All((r) => r.CheckRuleDataType<Symbols, LinkedListNode<Symbols>, Symbols>()) &&
                    PlotRules != null &&
                    PlotRules.All((r) => r.CheckRuleDataType<Symbols, Symbols, Action<DragonCurve, Turtle>>());
            }
        }
    }
}
